package com.zyf.project.binaryproto.specification;

import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;

/**
 * <h1>二进制数据片段的格式标准</h1>
 * <p>一个契约的实例 输出生成的二进制数据段 是由一系列的标准化的数据片段组成</p>
 * <p>这个类的构造函数是私有的，可以通过如下四个函数来创建对应的对象</p>
 * <ul>
 *     <li>{@link #newFixedSlice(int, String, String)}</li>
 *     <li>{@link #newRepeatableFixedSlice(int, String, String)}</li>
 *     <li>{@link #newDynamicSlice(String, String)}</li>
 *     <li>{@link #newRepeatableDynamicSlice(String, String)}</li>
 * </ul>
 *
 * @author Zhou Yifan
 */
public class BinarySliceSpecification {

    private final boolean repeatable;

    private final int length;

    private final boolean dynamic;

    private final String name;

    private final String description;

    /**
     * 是否重复多次，true 表示以一个头部表示接下来的片段将重复的次数
     *
     * @return 布尔值
     */
    public boolean isRepeatable() {
        return repeatable;
    }

    /**
     * 获取字节长度
     *
     * @return int 值
     */
    public int getLength() {
        return length;
    }

    /**
     * 长度是否是动态扩展的
     *
     * @return 布尔值
     */
    public boolean isDynamic() {
        return dynamic;
    }

    public String getName() {
        return name;
    }

    public String getDescription() {
        return description;
    }

    private BinarySliceSpecification(String name, String description, boolean repeatable, int length, boolean dynamic) {
        this.name = name;
        this.description = description;
        this.repeatable = repeatable;
        this.length = length;
        this.dynamic = dynamic;
    }

    /**
     * 片段无重复、且长度非动态扩展
     *
     * @param length      字节长度
     * @param name        名字
     * @param description 描述
     * @return new {@link BinarySliceSpecification}
     */
    @Contract(value = "_, _, _ -> new", pure = true)
    public static @NotNull BinarySliceSpecification newFixedSlice(int length, String name, String description) {
        return new BinarySliceSpecification(name, description, false, length, false);
    }

    /**
     * 片段可重复、且长度非动态扩展
     *
     * @param length      字节长度
     * @param name        名字
     * @param description 描述
     * @return new {@link BinarySliceSpecification}
     */
    @Contract(value = "_, _, _ -> new", pure = true)
    public static @NotNull BinarySliceSpecification newRepeatableFixedSlice(int length, String name, String description) {
        return new BinarySliceSpecification(name, description, true, length, false);
    }

    /**
     * 片段无重复、且长度动态扩展，初始长度 -1
     *
     * @param name        名字
     * @param description 描述
     * @return new {@link BinarySliceSpecification}
     */
    @Contract(value = "_, _ -> new", pure = true)
    public static @NotNull BinarySliceSpecification newDynamicSlice(String name, String description) {
        return new BinarySliceSpecification(name, description, false, -1, true);
    }

    /**
     * 片段可重复、且长度动态扩展，初始长度 -1
     *
     * @param name        名字
     * @param description 描述
     * @return new {@link BinarySliceSpecification}
     */
    @Contract(value = "_, _ -> new", pure = true)
    public static @NotNull BinarySliceSpecification newRepeatableDynamicSlice(String name, String description) {
        return new BinarySliceSpecification(name, description, true, -1, true);
    }
}
